using System;
using System.Collections.Generic;
using System.Reflection;
using Bingo.API.Config;
using CatLib;

namespace Bingo.Config
{
    public class ConfigSystem : IConfigSystem
    {
        private Dictionary<Type, ACategory> allConfig = new Dictionary<Type, ACategory>();

        public void Load()
        {
            Assembly assembly = this.GetType().Assembly;
            Type[] types = assembly.GetTypes();
            foreach (var type in types)
            {
                if (type.GetCustomAttribute(typeof(ConfigAttribute)) != null)
                {
                    object obj = Activator.CreateInstance(type);
                    ACategory iCategory = obj as ACategory;
                    if (iCategory == null)
                    {
                        throw new Exception($"class: {type.Name} not inherit from ACategory");
                    }

                    iCategory.BeginInit();
                    iCategory.EndInit();

                    this.allConfig[iCategory.ConfigType] = iCategory;
                    allConfig[iCategory.ConfigType] = iCategory;
                }
            }
        }

        public T GetOne<T>() where T : IConfig
        {
            ACategory configCategory;
            Type type = typeof(T);
            if (!this.allConfig.TryGetValue(type, out configCategory))
            {
                throw new Exception($"ConfigComponent not found key: {type.FullName}");
            }

            return (T) configCategory.GetOne();
        }

        public T Get<T>(int id) where T : IConfig
        {
            Type type = typeof(T);
            ACategory configCategory;
            if (!this.allConfig.TryGetValue(type, out configCategory))
            {
                throw new Exception($"ConfigComponent not found key: {type.FullName}");
            }

            return (T) configCategory.TryGet(id);
        }

        public T TryGet<T>(int id) where T : IConfig
        {
            Type type = typeof(T);
            ACategory configCategory;
            if (!this.allConfig.TryGetValue(type, out configCategory))
            {
                throw new Exception($"ConfigComponent not found key: {type.FullName}");
            }

            return (T) configCategory.TryGet(id);
        }

        public IConfig[] GetAll(Type type)
        {
            ACategory configCategory;
            if (!this.allConfig.TryGetValue(type, out configCategory))
            {
                throw new Exception($"ConfigComponent not found key: {type.FullName}");
            }

            return configCategory.GetAll();
        }
    }
}